import redis.clients.jedis.*;

import java.util.ArrayList;
import java.util.List;

/**
 * Redis工具类
 *
 * @author afei
 * @date 2016/7/15
 */


public class RedisUtil {
    /**
     * Redis服务器IP
     */
    private static String ADDRESS = "127.0.0.1";

    /**
     * Redis的端口号
     */
    private static int PORT = 6379;

    /**
     * 可用连接实例的最大数目，默认值为8
     */
    private static int MAX_ACTIVE = 1024;

    /**
     * 控制一个pool最多有多少个状态为idle(空闲的)的jedis实例，默认值8
     */
    private static int MAX_IDLE = 200;

    /**
     * 待可用连接的最大时间，单位毫秒，默认值为-1，表示永不超时。如果超过等待时间，则直接抛出JedisConnectionException
     */
    private static int MAX_WAIT = 10000;

    private static int TIMEOUT = 10000;

    /**
     * 在borrow一个jedis实例时，是否提前进行validate操作；如果为true，则得到的jedis实例均是可用的
     */
    private static boolean TEST_ON_BORROW = true;

    /**
     * 非切片连接池（单机）
     */
    private static JedisPool jedisPool;

    /**
     * 切片连接池(集群)
     */
    private static ShardedJedisPool shardedJedisPool;

    /**
     * 初始化Redis非切片池连接池
     */
    static {
        try {
            JedisPoolConfig config = new JedisPoolConfig();
            config.setMaxTotal(MAX_ACTIVE);
            config.setMaxIdle(MAX_IDLE);
            config.setMaxWaitMillis(MAX_WAIT);
            config.setTestOnBorrow(TEST_ON_BORROW);
            jedisPool = new JedisPool(config, ADDRESS, PORT, TIMEOUT);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     *  初始化Redis切片池连接池
     */
    static {
        // 池基本配置
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxTotal(MAX_ACTIVE);
        config.setMaxIdle(MAX_IDLE);
        config.setMaxWaitMillis(MAX_WAIT);
        config.setTestOnBorrow(TEST_ON_BORROW);
        // slave链接
        List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>();
        shards.add(new JedisShardInfo(ADDRESS, PORT, "master"));

        // 构造池
        shardedJedisPool = new ShardedJedisPool(config, shards);
    }

    /**
     * 获取Jedis实例
     *
     * @return
     */
    public synchronized static Jedis getJedis() {
        try {
            return jedisPool != null ? jedisPool.getResource() : null;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 获取 ShardedJedis实例
     *
     * @return
     */
    public synchronized static ShardedJedis getshardedJedis() {
        try {
            if (shardedJedisPool != null) {
                return shardedJedisPool.getResource();
            } else {
                return null;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 释放jedisPool资源
     *
     * @param jedisPool
     */
    public static void closeJedisPool(final JedisPool jedisPool) {
        if (jedisPool != null) {
            jedisPool.close();
        }
    }

    /**
     * 释放shardedJedisPool资源
     *
     * @param shardedJedisPool
     */
    public static void closeShardedJedisPool(final ShardedJedisPool shardedJedisPool) {
        if (shardedJedisPool != null) {
            shardedJedisPool.close();
        }
    }

    /**
     * 释放jedis资源
     *
     * @param jedis
     */
    public static void releaseJedis(final Jedis jedis) {
        System.out.println("oh ~ releaseJedis() be called!");
        if (jedis != null) {
            jedis.close();
        }
    }

    /**
     * 释放shardedJedis资源
     *
     * @param shardedJedis
     */
    public static void releaseShardedJedis(final ShardedJedis shardedJedis) {
        System.out.println("oh ~ releaseShardedJedis() be called!");
        if (shardedJedis != null) {
            shardedJedis.close();
        }
    }

    public static JedisPool getJedisPool() {
        return jedisPool == null ? null : jedisPool;
    }

    public static ShardedJedisPool getShardedJedisPool() {
        return shardedJedisPool == null ? null : shardedJedisPool;
    }
}
